package com.lagou.edu.handler;

import com.lagou.edu.context.stereotype.Transactional;
import com.lagou.edu.utils.TransactionManager;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Author zhaozuowen
 * @Description
 * @Date 2020/1/7 21:41
 **/

public class TransactionMethodInterceptor implements MethodInterceptor {

    private TransactionManager transactionManager;
    private Object targetObject;

    public TransactionMethodInterceptor() {
    }

    public TransactionMethodInterceptor(TransactionManager transactionManager, Object targetObject) {
        this.transactionManager = transactionManager;
        this.targetObject = targetObject;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        Object result = null;
        //判断方法是否有@Transaction注解，如果有则进行事务控制
        Class<?> declaringClass = method.getDeclaringClass();
        Transactional annotation=null;
        if(!declaringClass.isInterface()){
            annotation = method.getDeclaredAnnotation(Transactional.class);
        }else{
            Class<?>[] parameterTypes=method.getParameterTypes();
            Method declaredMethod = targetObject.getClass().getDeclaredMethod(method.getName(), parameterTypes);
            annotation = declaredMethod.getDeclaredAnnotation(Transactional.class);
        }
        if(annotation!=null){
            try{
                // 开启事务(关闭事务的自动提交)
                transactionManager.beginTransaction();
                result = method.invoke(targetObject,args);
                // 提交事务
                transactionManager.commit();
            }catch (Exception e) {
                e.printStackTrace();
                // 回滚事务
                transactionManager.rollback();
                // 抛出异常便于上层servlet捕获
                throw e;
            }
        }else{
            result = method.invoke(obj,targetObject);
        }


        return result;
    }
}
